import { Card } from "../card/Card";
import { Player } from "../player/Player";

export interface Process {
    text: string,
    user: Player,
    target?: Player,
    userCard?: Card | null,
    targetCard?: Card | null,
    props?: any
}

class SceneJson {

    public playerId: string = "";

    // 手牌
    public shoupai: Card[] = [];

    // 卡组
    public cards: Card[] = [];

    // 墓地
    public mudi: Card[] = [];

    // 前场
    public qianchang: Card[] = [];

    // 后场
    public houchang: Card[] = [];

    constructor (player: Player){
        this.playerId = player.id;

        this.cards = player.cards;
    }

}

export class Scene {

    /** 用户组 */
    public players: Array<Player> = [];

    /** 流程动作 */
    public processArray: Process[] = [];

    public player1: Player | any;

    public player2: Player | any;

    public sceneJson: SceneJson[] = [];

    /** 构造函数 */
    constructor (){

        // 等待用户假如
        this.awaitPlayer();

    }

    /**
     * 等待用户加入
     */
    public async awaitPlayer (){

        // 添加用户
        this.addPlayer(new Player("1", "用户1"));
        this.addPlayer(new Player("2", "用户2"));

        // 生成用户的卡组加载
        // await this.players[0].loadCard();
        // await this.players[1].loadCard();

        this.player1 = this.players[1];
        this.player2 = this.players[0];

        this.sceneJson.push(new SceneJson(this.players[0]))
        this.sceneJson.push(new SceneJson(this.players[1]))

        // 首先开始分配初始手牌
        await this.playerDrawer(this.players[0],4);
        await this.playerDrawer(this.players[1],4);

        // 开始主流程 这是一个async异步函数 不要在下面写同步流程 可以在then写后续流程
        this.startGame();

    }

    /**
     * 注册用户进入
     */
    addPlayer(player: Player){
        console.log("用户登录" + player.id);
        this.players.push(player);
    }

    /** 开始主流程 */
    async startGame (){

        console.log("开始主流程");
        
        // 计算谁先手  或者切换回合
        this.computeFristPlayer();

        // 开始当前回合用户的流程
        await this.playerProcess();

    }

    /**
     * 计算谁先开始 
     */
    computeFristPlayer (){
        if( this.player1 ){
            const p = this.player1;
            this.player1 = this.player2;
            this.player2 = p;
        }else{
            this.player1 = this.players[0];
            this.player2 = this.players[1];
        }
        console.log("计算谁的回合开始", this.player1.name);
    }

    /**
     * 用户回合流程
     */
    async playerProcess (){
        
        // 用户抽卡
        await this.playerDrawer();

        // 进入主要回合
        await this.playerMainProcess();

        // 等待用户操作
        await this.awaitPlayerOperate(this.player1);

        // 回合结束
        await this.closePlayerProcess();
        
    }

    async closePlayerProcess (){

        console.log("回合结束", this.player1.name);
        
        // 回合结束
        this.playerProcess();

        // 计算谁先手  或者切换回合
        this.computeFristPlayer();

    }

    setProcess (process: Process){
        // 记录到数组保存
        this.processArray.push(process)
        // 将流程发送给用户等待响应
        return this.sendPlayerProcess(process);
    }

    sendPlayerProcess (process: Process){
        return Promise.all(this.players.map((p)=> p.sendProcess(process)));
    }

    getOtherPlayer (player: Player){
        return this.players.find((e)=> e != player);
    }

    getSceneJson ( player: Player ){
        return this.sceneJson.find((e)=> e.playerId === player.id) || this.sceneJson[0];
    }

    // 用户抽卡
    async playerDrawer (player = this.player1,num = 1){

        console.log("进入抽卡模式", player.name)
        
        // 获取数据json
        const json = this.getSceneJson(player);

        // 将卡组中的
        json.shoupai.push(json.cards[0])
        json.cards.shift();

        // 等待用户抽卡
        await this.setProcess({ 
            text: "等待抽卡",
            user: player,
            target: this.getOtherPlayer(player),
            userCard: null,
            targetCard: null,
            props: {
                num
            }
        })
    }

    // 主要回合开始
    async playerMainProcess (){
        // 等待用户抽卡
        await this.setProcess({ 
            text: "进入主要会合",
            user: this.player1,
            target: this.player2,
            userCard: null,
            targetCard: null
        })

    }

    // 监听用户操作
    async awaitPlayerOperate (player: Player){

        // 获取数据json
        const json = this.getSceneJson(player);

        console.log("可以使用的卡片", json.shoupai.map((e)=> e.xid));
       
        // 主要回合选择等待抽卡
        return this.setProcess({
            text: "等待用户选择",
            user: player,
            target: this.getOtherPlayer(player),
            userCard: null,
            targetCard: null
        }).then((id: any)=> {
            console.log("使用卡牌", id);
            return id;
        })

    }

    // 收集场上可触发对象
    get (){

    }

}